#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>

using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::string;

#define Size 4096

const char*pathname ="/home/ryan/Linux_code/linux/32_shm_test/test.cpp";
const int proj_id = 0x11223344; 

int main()
{
    key_t key = ftok(pathname,proj_id);
    if(key<0)
    {
        cerr<<"errno:"<<errno<<" strerrno:"<<strerror(errno)<<endl;
        exit(1);    
    }
    sleep(1);

    //申请共享内存 , shmflag IPC_CREAT|IPC_EXCL保证该共享内存是全新的

    int shm_id=shmget(key,Size,IPC_CREAT|IPC_EXCL| 0664) ;
    if(shm_id<0)
    {
        cerr<<"errno:"<<errno<<" strerrno:"<<strerror(errno)<<endl;
        exit(1);    
    }
    else
    {
        cout<<"创建共享内存成功,shm_id:"<<shm_id<<endl;
    }
    sleep(1);

    //挂载共享内存,使其与进程链接，使其可以直接像字符数组那样运用
    char* shm_ptr =(char*)shmat(shm_id,nullptr,0);
    if((void*)-1 == (void*)shm_ptr)
    {
        cerr<<"errno:"<<errno<<" strerrno:"<<strerror(errno)<<endl;
        exit(1);    
    }
    else
    {
        cout<<"共享内存与当前进程挂载成功！"<<endl;
    }
    sleep(1);


    //取消挂载，使共享内存与进程剥离
    int n = shmdt((void*)shm_ptr);
    if(n<0)
    {
        cerr<<"errno:"<<errno<<" strerrno:"<<strerror(errno)<<endl;
        exit(1); 
    }
    else
    {
        cout<<"当前进程已经取消挂载shm_id:"<<shm_id<<"的共享内存"<<endl;
    }
    sleep(1);

    //删除共享内存
    int num = shmctl(shm_id,IPC_RMID,nullptr);
     if(num<0)
    {
        cerr<<"errno:"<<errno<<" strerrno:"<<strerror(errno)<<endl;
        exit(1); 
    }
    else
    {
        cout<<"shm_id:"<<shm_id<<"的共享内存已删除"<<endl<<"系统退出!"<<endl;
    }

}